{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Задание 1.\n",
    "\n",
    "Обязательная часть\n",
    "\n",
    "Будем парсить страницу со свежеми новостям на habr.com/ru/all/.\n",
    "\n",
    "Вам необходимо собирать только те статьи, в которых встречается хотя бы одно требуемое ключевое слово. Эти слова определяем в начале кода в переменной, например:\n",
    "\n",
    "KEYWORDS = ['python', 'парсинг']\n",
    "\n",
    "Поиск вести по всей доступной preview-информации (это информация, доступная непосредственно с текущей страницы).\n",
    "\n",
    "В итоге должен формироваться датафрейм со столбцами: - - ."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import requests\n",
    "import pandas as pd\n",
    "from datetime import datetime, timedelta\n",
    "from bs4 import BeautifulSoup\n",
    "from time import sleep\n",
    "import urllib3\n",
    "import re\n",
    "\n",
    "urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def habrdate2datetime(habrdate:str):\n",
    "    \"\"\"\n",
    "    Преобразование дат статей Habr в формат datetime\n",
    "    \n",
    "    Входные параметры:\n",
    "        habrdate -- дата статьи Хабра в формате строки \n",
    "                    Примеры: 'сегодня в 04:05', '2 октября 2020 в 18:02'\n",
    "                    \n",
    "    Возвращаемое значение: datetime. В случае ошибки возвращаеся 1 Января 1900\n",
    "    \"\"\"\n",
    "    \n",
    "    habrdate = habrdate.lower()\n",
    "    \n",
    "    # Возвращаемое значение функции, инициализируем его датой 1 Января 1900\n",
    "    # Отдаем такую дату в случае ошибок функции\n",
    "    dt_habrdate = datetime(1900, 1, 1)\n",
    "    \n",
    "    # Пробуем найти часы и минуты\n",
    "    re_post_time = re.compile(r'\\d\\d:\\d\\d$').findall(habrdate)\n",
    "    if len(re_post_time) == 0:\n",
    "        return dt_habrdate\n",
    "\n",
    "    # Сохраняем часы и минуты в формате HH:MM\n",
    "    post_time = re_post_time[0]\n",
    "\n",
    "    # Если в дате есть слово 'сегодня' или 'вчера', то сразу формируем datetime \n",
    "    # за сегодняшнюю или вчерашнюю дату\n",
    "    if any([word in habrdate for word in ('сегодня', 'вчера')]):\n",
    "        time = datetime.now() if 'сегодня' in habrdate else datetime.now() - timedelta(1)\n",
    "        dt_habrdate = datetime(time.year,time.month, \n",
    "                               time.day, int(post_time.split(':')[0]), int(post_time.split(':')[1]))\n",
    "        \n",
    "    #В случае если в дате указано русское название месяца, то меняем на английское значение\n",
    "    # и конвертируем дату в datetime\n",
    "    else:\n",
    "        \n",
    "        if 'января' in habrdate:\n",
    "            habrdate = habrdate.replace('января', 'January')\n",
    "        elif 'февраля' in habrdate:\n",
    "            habrdate = habrdate.replace('февраля', 'February')\n",
    "        elif 'марта' in habrdate:\n",
    "            habrdate = habrdate.replace('марта', 'March')\n",
    "        elif 'апреля' in habrdate:\n",
    "            habrdate = habrdate.replace('апреля', 'April')\n",
    "        elif 'мая' in habrdate:\n",
    "            habrdate = habrdate.replace('мая', 'May')\n",
    "        elif 'июня' in habrdate:\n",
    "            habrdate = habrdate.replace('июня', 'June')\n",
    "        elif 'июля' in habrdate:\n",
    "            habrdate = habrdate.replace('июля', 'Jule')\n",
    "        elif 'августа' in habrdate:\n",
    "            habrdate = habrdate.replace('августа', 'August')\n",
    "        elif 'сентября' in habrdate:\n",
    "            habrdate = habrdate.replace('сентября', 'September')\n",
    "        elif 'октября' in habrdate:\n",
    "            habrdate = habrdate.replace('октября', 'October')\n",
    "        elif 'ноября' in habrdate:\n",
    "            habrdate = habrdate.replace('ноября', 'November')\n",
    "        elif 'декабря' in habrdate:\n",
    "            habrdate = habrdate.replace('декабря', 'December')\n",
    "\n",
    "        # С помощью регулярного выражения находим дату в формате ДЕНЬ НАЗВАНИЕ МЕСЯЦА ГОД\n",
    "        re_date = re.compile(r'\\d{1,2}\\s\\w+\\s\\d{4}').findall(habrdate)\n",
    "        if len(re_date) == 0:\n",
    "            return dt_habrdate\n",
    "        \n",
    "        # Формируем datetime из полученных данных\n",
    "        try:\n",
    "            dt_habrdate = datetime.strptime(re_date[0]+ f\" {post_time.split(':')[0]}:{post_time.split(':')[1]}\", \n",
    "                                            f\"%d %B %Y %H:%M\") \n",
    "        except:\n",
    "            return dt_habrdate \n",
    "        \n",
    "    return dt_habrdate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_habr_posts_by_keywords(keywords:list, pages:int=1):\n",
    "    \"\"\"\n",
    "    Функция для поиска постов с определенными ключевыми словами в тексте.\n",
    "    \n",
    "    Входные параметры:\n",
    "      keywords -- список с ключевыми словами, например, ['python', 'парсинг']\n",
    "      pages -- количество страниц для анализа\n",
    "      \n",
    "    Возвращаемое значение: датафрейм Pandas\n",
    "    \"\"\"\n",
    "    \n",
    "    df = pd.DataFrame()\n",
    "    \n",
    "    for page_number in range(1, pages+1):\n",
    "        \n",
    "        # получаем страницу с указанным номером с самыми свежими постами\n",
    "        web_response = requests.get(f'https://habr.com/ru/all/page{page_number}/', verify=False)\n",
    "        bs = BeautifulSoup(web_response.text, 'html.parser')\n",
    "        \n",
    "        # Все блоки постов находятся в тегах article с классом post\n",
    "        posts = bs.find_all('article', class_='post')\n",
    "        \n",
    "        # Перебираем все найденные посты на странице\n",
    "        for post in posts:\n",
    "            \n",
    "            # Получаем объект bs с заголовком поста\n",
    "            post_title = post.find('a', class_='post__title_link')\n",
    "            \n",
    "            # Получаем объект bs с кратким описанием поста\n",
    "            post_description = post.find('div', class_='post__text')\n",
    "            \n",
    "            # Создаем общий текст для анализа заголовок + описание\n",
    "            analyse_text = (post_title.text + post_description.text).lower()\n",
    "            \n",
    "            # Если объекты заголовка и краткого описания поста не найдены, считаем это некорректным вариантом\n",
    "            if not post_title or not post_description:\n",
    "                # Чтобы поймать ошибки разного форматирования сделаем принт для диагностики проблемы\n",
    "                print(f\"Не удалось найти заголовок|краткое описание статьи habr\")\n",
    "                continue\n",
    "            \n",
    "            # Если хоть одно ключевое слово содержится в заголовке и описании, то добавляем пост в датафрейм\n",
    "            if any([keyword.lower() in analyse_text for keyword in keywords]):\n",
    "\n",
    "                # Получаем ссылку на полную версию поста\n",
    "                post_link = post_title.get('href')\n",
    "\n",
    "                # Получаем дату размещения\n",
    "                date_post = post.find('span', class_='post__time')\n",
    "\n",
    "                # Если найдена дата поста, то пробуем ее преобразовать в формат datetime\n",
    "                if date_post:\n",
    "                    date_post = habrdate2datetime(date_post.text)\n",
    "        \n",
    "                row = {'page': page_number, \n",
    "                       'date': date_post,\n",
    "                       'title': post_title.text.strip(), \n",
    "                       'link': post_link}    \n",
    "                df = pd.concat([df, pd.DataFrame([row])])\n",
    "\n",
    "        # Задержка перед парсингом следующей страницы\n",
    "        sleep(0.5)\n",
    "        \n",
    "    # Добавляем корректный индекс в итоговый датафрейм\n",
    "    df.index = [i for i in range(len(df))]\n",
    "    \n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>page</th>\n",
       "      <th>date</th>\n",
       "      <th>title</th>\n",
       "      <th>link</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>2020-10-05 23:31:00</td>\n",
       "      <td>Выход стабильной версии Python 3.9.0</td>\n",
       "      <td>https://habr.com/ru/post/522170/</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>2020-10-05 18:26:00</td>\n",
       "      <td>Разработка графического профайлера Python Func...</td>\n",
       "      <td>https://habr.com/ru/company/skillfactory/blog/...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>2020-10-05 17:27:00</td>\n",
       "      <td>Serverless телеграм бот с использованием Яндек...</td>\n",
       "      <td>https://habr.com/ru/post/522126/</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2</td>\n",
       "      <td>2020-10-05 16:11:00</td>\n",
       "      <td>Отношение один к одному: связывание модели пол...</td>\n",
       "      <td>https://habr.com/ru/company/otus/blog/522106/</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   page                date  \\\n",
       "0     1 2020-10-05 23:31:00   \n",
       "1     1 2020-10-05 18:26:00   \n",
       "2     1 2020-10-05 17:27:00   \n",
       "3     2 2020-10-05 16:11:00   \n",
       "\n",
       "                                               title  \\\n",
       "0               Выход стабильной версии Python 3.9.0   \n",
       "1  Разработка графического профайлера Python Func...   \n",
       "2  Serverless телеграм бот с использованием Яндек...   \n",
       "3  Отношение один к одному: связывание модели пол...   \n",
       "\n",
       "                                                link  \n",
       "0                   https://habr.com/ru/post/522170/  \n",
       "1  https://habr.com/ru/company/skillfactory/blog/...  \n",
       "2                   https://habr.com/ru/post/522126/  \n",
       "3      https://habr.com/ru/company/otus/blog/522106/  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "KEYWORDS = ['python', 'парсинг']\n",
    "df_posts = get_habr_posts_by_keywords(KEYWORDS, pages=5)\n",
    "display(df_posts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Дополнительная часть (необязательная)\n",
    "\n",
    "Улучшить скрипт так, чтобы он анализировал не только preview-информацию статьи, но и весь текст статьи целиком.\n",
    "\n",
    "Для этого потребуется получать страницы статей и искать по тексту внутри этой страницы.\n",
    "\n",
    "Итоговый датафрейм формировать со столбцами: - - - <текст статьи>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_habr_posts_by_keywords(keywords:list, pages:int=5):\n",
    "    \"\"\"\n",
    "    Функция для поиска постов с определенными ключевыми словами в тексте.\n",
    "    \n",
    "    Входные параметры:\n",
    "      keywords -- список с ключевыми словами, например, ['python', 'парсинг']\n",
    "      pages -- количество страниц для анализа\n",
    "      \n",
    "    Возвращаемое значение: датафрейм Pandas\n",
    "    \"\"\"\n",
    "\n",
    "    df = pd.DataFrame()\n",
    "    \n",
    "    for page_number in range(1, pages+1):\n",
    "        \n",
    "        # получаем страницу с указанным номером с самыми свежими постами\n",
    "        web_response = requests.get(f'https://habr.com/ru/all/page{page_number}/', verify=False)\n",
    "        bs = BeautifulSoup(web_response.text, 'html.parser')\n",
    "        \n",
    "        # Все блоки постов находятся в тегах article с классом post\n",
    "        posts = bs.find_all('article', class_='post')\n",
    "        \n",
    "        # Перебираем все найденные посты на странице\n",
    "        for post in posts:\n",
    "            \n",
    "            # Флаг post_is_matched сигнализирует о том, что в данных поста найденны ключевые слова.\n",
    "            # Здесь происходит инициализация переменной, во время анализа поста может измениться на True\n",
    "            post_is_matched = False\n",
    "            \n",
    "            # Получаем объект bs с заголовком поста\n",
    "            post_title = post.find('a', class_='post__title_link')\n",
    "            \n",
    "            # Получаем объект bs с кратким описанием поста\n",
    "            post_description = post.find('div', class_='post__text')\n",
    "            \n",
    "            # Получаем ссылку на полную версию поста\n",
    "            post_link = post_title.get('href')\n",
    "            \n",
    "            # Получаем дату размещения\n",
    "            date_post = post.find('span', class_='post__time')\n",
    "            \n",
    "            # Если объекты заголовка, краткого описания поста или ссылка на пост не найдены, \n",
    "            # считаем это некорректным вариантом и пропускаем\n",
    "            if not post_title or not post_description or not post_link:\n",
    "                # Чтобы поймать ошибки разного форматирования сделаем принт для диагностики проблемы\n",
    "                print(f\"Не удалось найти заголовок|краткое описание|ссылку статьи habr\")\n",
    "                continue\n",
    "                                     \n",
    "            # Создаем общий текст для анализа заголовок + описание\n",
    "            analyse_text = (post_title.text + post_description.text).lower()\n",
    "            \n",
    "            # Если хоть одно ключевое слово содержится в заголовке и описании, то добавляем пост в датафрейм\n",
    "            if any([keyword.lower() in analyse_text for keyword in keywords]):\n",
    "                post_is_matched = True \n",
    "             \n",
    "            # Если в краткой версии поста не найдены ключевые слова, пробуем открыть полную версию поста\n",
    "            # и искать ключевые слова в полной версии\n",
    "            else:\n",
    "                # Задержка перед парсингом следующей страницы\n",
    "                sleep(0.5)\n",
    "                \n",
    "                web_response = requests.get(post_link, verify=False)\n",
    "                bs = BeautifulSoup(web_response.text, 'html.parser')\n",
    "                \n",
    "                # Полная версия поста находится в контейнере div с классом post__body\n",
    "                post_body_full = bs.find('div', class_='post__body')  \n",
    "                \n",
    "                if not post_body_full:\n",
    "                    # Чтобы поймать ошибки разного форматирования сделаем принт для диагностики проблемы\n",
    "                    print(f\"Не найден полный текст поста по ссылке {post_link}\")\n",
    "                    continue\n",
    "                    \n",
    "                # Если хоть одно ключевое слово содержится в тексте полного поста, \n",
    "                # то добавляем его в датафрейм    \n",
    "                if any([keyword.lower() in post_body_full.text for keyword in keywords]):\n",
    "                    post_is_matched = True\n",
    "                 \n",
    "            # Если нашли клчюевые слова в полном текте статьи или сокращенном, то добавляем данные\n",
    "            # в датафрейм\n",
    "            if post_is_matched:\n",
    "                \n",
    "                # Если найдена дата поста, то пробуем ее преобразовать в формат datetime\n",
    "                if date_post:\n",
    "                    date_post = habrdate2datetime(date_post.text)\n",
    "                \n",
    "                row = {'page': page_number, \n",
    "                       'date': date_post,\n",
    "                       'title': post_title.text.strip(), \n",
    "                       'link': post_link}    \n",
    "                df = pd.concat([df, pd.DataFrame([row])])\n",
    "                \n",
    "        # Задержка перед парсингом следующей страницы      \n",
    "        sleep(0.5)\n",
    "      \n",
    "    # Добавляем корректный индекс в итоговый датафрейм\n",
    "    df.index = [i for i in range(len(df))]\n",
    "    \n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>page</th>\n",
       "      <th>date</th>\n",
       "      <th>title</th>\n",
       "      <th>link</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>2020-10-05 23:31:00</td>\n",
       "      <td>Выход стабильной версии Python 3.9.0</td>\n",
       "      <td>https://habr.com/ru/post/522170/</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>2020-10-05 18:26:00</td>\n",
       "      <td>Разработка графического профайлера Python Func...</td>\n",
       "      <td>https://habr.com/ru/company/skillfactory/blog/...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>2020-10-05 17:27:00</td>\n",
       "      <td>Serverless телеграм бот с использованием Яндек...</td>\n",
       "      <td>https://habr.com/ru/post/522126/</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2</td>\n",
       "      <td>2020-10-05 16:11:00</td>\n",
       "      <td>Отношение один к одному: связывание модели пол...</td>\n",
       "      <td>https://habr.com/ru/company/otus/blog/522106/</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>3</td>\n",
       "      <td>2020-10-05 12:26:00</td>\n",
       "      <td>Http-stubs — поиск идеального инструмента</td>\n",
       "      <td>https://habr.com/ru/company/umatech/blog/521722/</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5</td>\n",
       "      <td>2020-10-04 12:48:00</td>\n",
       "      <td>Дайджест интересных материалов для мобильного ...</td>\n",
       "      <td>https://habr.com/ru/company/digital-ecosystems...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>5</td>\n",
       "      <td>2020-10-03 22:41:00</td>\n",
       "      <td>Токсичность Белорусского IT аутсорса</td>\n",
       "      <td>https://habr.com/ru/post/521928/</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   page                date  \\\n",
       "0     1 2020-10-05 23:31:00   \n",
       "1     1 2020-10-05 18:26:00   \n",
       "2     1 2020-10-05 17:27:00   \n",
       "3     2 2020-10-05 16:11:00   \n",
       "4     3 2020-10-05 12:26:00   \n",
       "5     5 2020-10-04 12:48:00   \n",
       "6     5 2020-10-03 22:41:00   \n",
       "\n",
       "                                               title  \\\n",
       "0               Выход стабильной версии Python 3.9.0   \n",
       "1  Разработка графического профайлера Python Func...   \n",
       "2  Serverless телеграм бот с использованием Яндек...   \n",
       "3  Отношение один к одному: связывание модели пол...   \n",
       "4          Http-stubs — поиск идеального инструмента   \n",
       "5  Дайджест интересных материалов для мобильного ...   \n",
       "6               Токсичность Белорусского IT аутсорса   \n",
       "\n",
       "                                                link  \n",
       "0                   https://habr.com/ru/post/522170/  \n",
       "1  https://habr.com/ru/company/skillfactory/blog/...  \n",
       "2                   https://habr.com/ru/post/522126/  \n",
       "3      https://habr.com/ru/company/otus/blog/522106/  \n",
       "4   https://habr.com/ru/company/umatech/blog/521722/  \n",
       "5  https://habr.com/ru/company/digital-ecosystems...  \n",
       "6                   https://habr.com/ru/post/521928/  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "KEYWORDS = ['python', 'парсинг']\n",
    "df_posts = get_habr_posts_by_keywords(KEYWORDS, pages=5)\n",
    "display(df_posts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Задание 2\n",
    "\n",
    "Обязательная часть\n",
    "\n",
    "Написать скрипт, который будет проверять список e-mail адресов на утечку при помощи сервиса Avast Hack Ckeck. Список email-ов задаем переменной в начале кода:\n",
    "\n",
    "EMAIL = [xxx@x.ru, yyy@y.com]\n",
    "\n",
    "В итоге должен формироваться датафрейм со столбцами: <почта> - <дата утечки> - <источник утечки> - <описание утечки>.\n",
    "\n",
    "Подсказка: сервис работает при помощи \"скрытого\" API. Внимательно изучите post-запросы."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def str2date(date):\n",
    "    \"\"\"\n",
    "    Функция для конвертации даты в формате строки в формат datetime. Функция возвращает\n",
    "    дату в формате datetime. Если в переменной str_date указан некорректный формат даты, \n",
    "    то функция выдаст исключение.\n",
    "    date - дата в формате YYYY-MM-DD\n",
    "    \"\"\"\n",
    "    \n",
    "    known_formats = [\n",
    "    '%A, %B %d, %Y', #  The Moscow Times - Wednesday, October 2, 2002\n",
    "    '%A, %d.%m.%y',  #  The Guardian - Friday, 11.10.13\n",
    "    '%A, %d %B %Y',  #  Daily News - Thursday, 18 August 1977\n",
    "    '%Y-%m-%d',      #  Формат YYYY-MM-DD\n",
    "    ]\n",
    "    \n",
    "    for datetime_format in known_formats:\n",
    "        try:\n",
    "            return datetime.strptime(date, datetime_format).date()\n",
    "        except:\n",
    "            pass\n",
    "    raise ValueError('date содержит неподдерживаемый формат времени')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>email</th>\n",
       "      <th>date</th>\n",
       "      <th>source</th>\n",
       "      <th>description</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2019-03-28</td>\n",
       "      <td>verifications.io</td>\n",
       "      <td>Big data e-mail verification platform verifica...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2020-05-21</td>\n",
       "      <td>vk.com</td>\n",
       "      <td>At some time in 2020, the Russian social netwo...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2017-02-14</td>\n",
       "      <td>parapa.mail.ru</td>\n",
       "      <td>In July and August 2016, two criminals execute...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2016-10-29</td>\n",
       "      <td>vk.com</td>\n",
       "      <td>Popular Russian social networking platform VKo...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2016-10-21</td>\n",
       "      <td>adobe.com</td>\n",
       "      <td>In October of 2013, criminals penetrated Adobe...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2020-09-10</td>\n",
       "      <td>na</td>\n",
       "      <td>This is a compilation of files including breac...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2017-02-14</td>\n",
       "      <td>cfire.mail.ru</td>\n",
       "      <td>In July and August of 2016, two criminals carr...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2017-01-31</td>\n",
       "      <td>cdprojektred.com</td>\n",
       "      <td>In March 2016, CDProjektRed.com.com's forum da...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>xxx@x.ru</td>\n",
       "      <td>2016-10-23</td>\n",
       "      <td>imesh.com</td>\n",
       "      <td>In June 2016, a cache of over 51 million user ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2019-03-28</td>\n",
       "      <td>verifications.io</td>\n",
       "      <td>Big data e-mail verification platform verifica...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2019-02-21</td>\n",
       "      <td>www.dangdang.com</td>\n",
       "      <td>This is a list of email addresses only, and as...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2020-01-03</td>\n",
       "      <td>azcentral.com</td>\n",
       "      <td>At an unconfirmed date, online Arizona newspap...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2020-05-28</td>\n",
       "      <td>wishbone.io</td>\n",
       "      <td>In January 2020, the online poll website Wishb...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2017-11-04</td>\n",
       "      <td>myheritage.com</td>\n",
       "      <td>In October 2017, a customer database belonging...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2017-12-01</td>\n",
       "      <td>creocommunity.com</td>\n",
       "      <td>At an unconfirmed date, Creo Community's user ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2019-06-13</td>\n",
       "      <td>canva.com</td>\n",
       "      <td>In May 2019, graphic-design site Canva's datab...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2016-10-24</td>\n",
       "      <td>dropbox.com</td>\n",
       "      <td>Cloud storage company Dropbox suffered a major...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2016-10-21</td>\n",
       "      <td>linkedin.com</td>\n",
       "      <td>In 2012, online professional networking platfo...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2017-03-01</td>\n",
       "      <td>rayli.com.cn</td>\n",
       "      <td>On an unconfirmed date, Chinese gossip site Ra...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2019-10-17</td>\n",
       "      <td>zynga.com</td>\n",
       "      <td>In September 2019, the game developer Zynga wa...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2019-07-11</td>\n",
       "      <td>medicaresupplement.com</td>\n",
       "      <td>In May 2019, a security researcher discovered ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2016-10-21</td>\n",
       "      <td>adobe.com</td>\n",
       "      <td>In October of 2013, criminals penetrated Adobe...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2018-02-18</td>\n",
       "      <td>netlog.com</td>\n",
       "      <td>Netlog (formerly known as Facebox and Bingbox)...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2017-03-15</td>\n",
       "      <td>globalreach.eu</td>\n",
       "      <td>In 2016, Global Reach Technology's database wa...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2016-10-23</td>\n",
       "      <td>imesh.com</td>\n",
       "      <td>In June 2016, a cache of over 51 million user ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>yyy@y.com</td>\n",
       "      <td>2017-03-24</td>\n",
       "      <td>youku.com</td>\n",
       "      <td>Youku is a large Chinese video content company...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        email        date                  source  \\\n",
       "0    xxx@x.ru  2019-03-28        verifications.io   \n",
       "1    xxx@x.ru  2020-05-21                  vk.com   \n",
       "2    xxx@x.ru  2017-02-14          parapa.mail.ru   \n",
       "3    xxx@x.ru  2016-10-29                  vk.com   \n",
       "4    xxx@x.ru  2016-10-21               adobe.com   \n",
       "5    xxx@x.ru  2020-09-10                      na   \n",
       "6    xxx@x.ru  2017-02-14           cfire.mail.ru   \n",
       "7    xxx@x.ru  2017-01-31        cdprojektred.com   \n",
       "8    xxx@x.ru  2016-10-23               imesh.com   \n",
       "9   yyy@y.com  2019-03-28        verifications.io   \n",
       "10  yyy@y.com  2019-02-21        www.dangdang.com   \n",
       "11  yyy@y.com  2020-01-03           azcentral.com   \n",
       "12  yyy@y.com  2020-05-28             wishbone.io   \n",
       "13  yyy@y.com  2017-11-04          myheritage.com   \n",
       "14  yyy@y.com  2017-12-01       creocommunity.com   \n",
       "15  yyy@y.com  2019-06-13               canva.com   \n",
       "16  yyy@y.com  2016-10-24             dropbox.com   \n",
       "17  yyy@y.com  2016-10-21            linkedin.com   \n",
       "18  yyy@y.com  2017-03-01            rayli.com.cn   \n",
       "19  yyy@y.com  2019-10-17               zynga.com   \n",
       "20  yyy@y.com  2019-07-11  medicaresupplement.com   \n",
       "21  yyy@y.com  2016-10-21               adobe.com   \n",
       "22  yyy@y.com  2018-02-18              netlog.com   \n",
       "23  yyy@y.com  2017-03-15          globalreach.eu   \n",
       "24  yyy@y.com  2016-10-23               imesh.com   \n",
       "25  yyy@y.com  2017-03-24               youku.com   \n",
       "\n",
       "                                          description  \n",
       "0   Big data e-mail verification platform verifica...  \n",
       "1   At some time in 2020, the Russian social netwo...  \n",
       "2   In July and August 2016, two criminals execute...  \n",
       "3   Popular Russian social networking platform VKo...  \n",
       "4   In October of 2013, criminals penetrated Adobe...  \n",
       "5   This is a compilation of files including breac...  \n",
       "6   In July and August of 2016, two criminals carr...  \n",
       "7   In March 2016, CDProjektRed.com.com's forum da...  \n",
       "8   In June 2016, a cache of over 51 million user ...  \n",
       "9   Big data e-mail verification platform verifica...  \n",
       "10  This is a list of email addresses only, and as...  \n",
       "11  At an unconfirmed date, online Arizona newspap...  \n",
       "12  In January 2020, the online poll website Wishb...  \n",
       "13  In October 2017, a customer database belonging...  \n",
       "14  At an unconfirmed date, Creo Community's user ...  \n",
       "15  In May 2019, graphic-design site Canva's datab...  \n",
       "16  Cloud storage company Dropbox suffered a major...  \n",
       "17  In 2012, online professional networking platfo...  \n",
       "18  On an unconfirmed date, Chinese gossip site Ra...  \n",
       "19  In September 2019, the game developer Zynga wa...  \n",
       "20  In May 2019, a security researcher discovered ...  \n",
       "21  In October of 2013, criminals penetrated Adobe...  \n",
       "22  Netlog (formerly known as Facebox and Bingbox)...  \n",
       "23  In 2016, Global Reach Technology's database wa...  \n",
       "24  In June 2016, a cache of over 51 million user ...  \n",
       "25  Youku is a large Chinese video content company...  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "EMAIL = ['xxx@x.ru', 'yyy@y.com']\n",
    "\n",
    "url = 'https://identityprotection.avast.com/v1/web/query/site-breaches/unauthorized-data'\n",
    "headers = {\n",
    "    'Vaar-Version': '0',\n",
    "    'Vaar-Header-App-Product': 'hackcheck-web-avast'\n",
    "}\n",
    "data = {'emailAddresses': EMAIL}\n",
    "response = requests.post(url, data=json.dumps(data), headers=headers, verify=False)\n",
    "\n",
    "if response.status_code != 200 or not response.text:\n",
    "    message = f\"Во время полученя данных с API произошла ошибка\"\n",
    "    print(message)   \n",
    "else:\n",
    "    df_breaches = pd.DataFrame()\n",
    "    response_json = json.loads(response.text)\n",
    "    for email, breaches_dict in response_json['summary'].items():\n",
    "        for breach_id in breaches_dict['breaches']:   \n",
    "            row = {'email': email,\n",
    "                   'date':  str2date(response_json['breaches'][str(breach_id)]['publishDate'][:10]),\n",
    "                   'source': response_json['breaches'][str(breach_id)]['site'],\n",
    "                   'description': response_json['breaches'][str(breach_id)]['description']\n",
    "                  }\n",
    "            df_breaches = pd.concat([df_breaches, pd.DataFrame([row])])\n",
    "    \n",
    "            \n",
    "    # Добавляем корректный индекс в итоговый датафрейм\n",
    "    df_breaches.index = [i for i in range(len(df_breaches))]\n",
    " \n",
    "    display(df_breaches)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Дополнительная часть (необязательная)\n",
    "\n",
    "Написать скрипт, который будет получать 50 последних постов указанной группы во Вконтакте.\n",
    "Документация к API VK: https://vk.com/dev/methods , вам поможет метод wall.getGROUP = 'netology'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "TOKEN = ''\n",
    "# Количество получаемых постов\n",
    "COUNT_POSTS = 100\n",
    "# Домен сообщества, например, для сообщества https://vk.com/onyxboox_russia домен onyxboox_russia\n",
    "GROUP_DOMAIN  = 'onyxboox_russia'\n",
    "# Версия API\n",
    "api_version = '5.124'\n",
    "\n",
    "url = 'https://api.vk.com/method/wall.get'\n",
    "params = {\n",
    "    'domain': GROUP_DOMAIN,\n",
    "    'count': COUNT_POSTS, \n",
    "    'access_token': TOKEN,\n",
    "    'v': api_version\n",
    "}\n",
    "\n",
    "json_api_response = json.loads(requests.post(url, data=params, verify=False).text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>date</th>\n",
       "      <th>text</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2016-11-07 07:36:40</td>\n",
       "      <td>Только для своих! ;) \\nСкидка 5% нашим подписч...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2020-10-04 13:32:59</td>\n",
       "      <td>Целая семья букридеров ONYX, включая даже деду...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2020-10-03 17:29:02</td>\n",
       "      <td>В сентябре вышел трейлер «Дюны» Дени Вильнева ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2020-10-02 13:01:57</td>\n",
       "      <td>📖 Брайан Стивенсон «Звонок за ваш счет. Истори...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2020-10-01 16:17:51</td>\n",
       "      <td>Poke 2 – маленький, да удаленький! \\nМодель им...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>2020-09-30 15:52:59</td>\n",
       "      <td>Американские ученые провели исследование и выя...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2020-09-29 12:17:02</td>\n",
       "      <td>Борис Акунин рассказал, что подготовил для дет...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>2020-09-28 16:44:10</td>\n",
       "      <td>То чувство, когда человеческий портрет не пере...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>2020-09-27 14:41:56</td>\n",
       "      <td>Я любитель привидений. Я никогда не слыхал, чт...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>2020-09-26 14:48:16</td>\n",
       "      <td>📖 Мадлен Миллер «Цирцея». \\n\\nМадлен Миллер – ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 date                                               text\n",
       "0 2016-11-07 07:36:40  Только для своих! ;) \\nСкидка 5% нашим подписч...\n",
       "1 2020-10-04 13:32:59  Целая семья букридеров ONYX, включая даже деду...\n",
       "2 2020-10-03 17:29:02  В сентябре вышел трейлер «Дюны» Дени Вильнева ...\n",
       "3 2020-10-02 13:01:57  📖 Брайан Стивенсон «Звонок за ваш счет. Истори...\n",
       "4 2020-10-01 16:17:51  Poke 2 – маленький, да удаленький! \\nМодель им...\n",
       "5 2020-09-30 15:52:59  Американские ученые провели исследование и выя...\n",
       "6 2020-09-29 12:17:02  Борис Акунин рассказал, что подготовил для дет...\n",
       "7 2020-09-28 16:44:10  То чувство, когда человеческий портрет не пере...\n",
       "8 2020-09-27 14:41:56  Я любитель привидений. Я никогда не слыхал, чт...\n",
       "9 2020-09-26 14:48:16  📖 Мадлен Миллер «Цирцея». \\n\\nМадлен Миллер – ..."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Первый метод формирования датафрейма, более быстрый\n",
    "if json_api_response.get('error'):\n",
    "    message = f\"Во время полученя данных с API произошла ошибка: {json_api_response['error']['error_msg']}\"\n",
    "    print(message)   \n",
    "else:\n",
    "    # Создадим датафрейм со столбцами Дата, Текст поcта\n",
    "    dates = []\n",
    "    texts = []\n",
    "    for post in json_api_response['response']['items']:\n",
    "        dates.append(post.get('date'))\n",
    "        texts.append(post.get('text'))\n",
    "\n",
    "    df_vk_posts = pd.DataFrame({'date': dates, 'text': texts})\n",
    "    # Преоборазовываем unixtime в datetime\n",
    "    df_vk_posts.date = pd.to_datetime(df_vk_posts.date, unit='s')\n",
    "\n",
    "    display(df_vk_posts[:10])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>date</th>\n",
       "      <th>text</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2016-11-07 07:36:40</td>\n",
       "      <td>Только для своих! ;) \\nСкидка 5% нашим подписч...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2020-10-04 13:32:59</td>\n",
       "      <td>Целая семья букридеров ONYX, включая даже деду...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2020-10-03 17:29:02</td>\n",
       "      <td>В сентябре вышел трейлер «Дюны» Дени Вильнева ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2020-10-02 13:01:57</td>\n",
       "      <td>📖 Брайан Стивенсон «Звонок за ваш счет. Истори...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2020-10-01 16:17:51</td>\n",
       "      <td>Poke 2 – маленький, да удаленький! \\nМодель им...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>2020-09-30 15:52:59</td>\n",
       "      <td>Американские ученые провели исследование и выя...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2020-09-29 12:17:02</td>\n",
       "      <td>Борис Акунин рассказал, что подготовил для дет...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>2020-09-28 16:44:10</td>\n",
       "      <td>То чувство, когда человеческий портрет не пере...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>2020-09-27 14:41:56</td>\n",
       "      <td>Я любитель привидений. Я никогда не слыхал, чт...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>2020-09-26 14:48:16</td>\n",
       "      <td>📖 Мадлен Миллер «Цирцея». \\n\\nМадлен Миллер – ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 date                                               text\n",
       "0 2016-11-07 07:36:40  Только для своих! ;) \\nСкидка 5% нашим подписч...\n",
       "1 2020-10-04 13:32:59  Целая семья букридеров ONYX, включая даже деду...\n",
       "2 2020-10-03 17:29:02  В сентябре вышел трейлер «Дюны» Дени Вильнева ...\n",
       "3 2020-10-02 13:01:57  📖 Брайан Стивенсон «Звонок за ваш счет. Истори...\n",
       "4 2020-10-01 16:17:51  Poke 2 – маленький, да удаленький! \\nМодель им...\n",
       "5 2020-09-30 15:52:59  Американские ученые провели исследование и выя...\n",
       "6 2020-09-29 12:17:02  Борис Акунин рассказал, что подготовил для дет...\n",
       "7 2020-09-28 16:44:10  То чувство, когда человеческий портрет не пере...\n",
       "8 2020-09-27 14:41:56  Я любитель привидений. Я никогда не слыхал, чт...\n",
       "9 2020-09-26 14:48:16  📖 Мадлен Миллер «Цирцея». \\n\\nМадлен Миллер – ..."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Второй метод формирования датафрейма, работает в 2 раа медленнее предыдущего\n",
    "if json_api_response.get('error'):\n",
    "    message = f\"Во время полученя данных с API произошла ошибка: {json_api_response['error']['error_msg']}\"\n",
    "    print(message)   \n",
    "else:\n",
    "    df_vk_posts = pd.DataFrame(json_api_response['response']['items']).loc[:, ['date', 'text']]\n",
    "    # Преоборазовываем unixtime в datetime\n",
    "    df_vk_posts.date = pd.to_datetime(df_vk_posts.date, unit='s')\n",
    "\n",
    "    display(df_vk_posts[:10])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
